/*
 * @Author: yuluo
 * @Date: 2025-08-28
 * @LastEditors: yuluo
 * @LastEditTime: 2025-09-21
 * @FilePath: \Projecte:\gitee\GD32F427\gd32-f427-BootLoader\BSP\src\drv_key.c
 * @Description:
 * 如有特殊注意事项请填写
 * Copyright (c) by ${yuluo}, All Rights Reserved.
 */

#include "main.h"

/**
 * @description: 按键引脚初始化
 * @return {*}
 */
void drv_key_init(void)
{
    /* 开时钟 */
    rcu_periph_clock_enable(KEY0_RCU | KEY_WK_UP_RCU);

    /* 设置模式 */
    gpio_mode_set(KEY0_PORT, GPIO_MODE_INPUT, KEY0_PUPD, KEY0_PIN);
    gpio_mode_set(KEY_WK_UP_PORT, GPIO_MODE_INPUT, KEY_WK_UP_PUPD, KEY_WK_UP_PIN);
}

/**
 * @description: KEY0读取电平函数
 * @return {*}
 */
static uint8_t key0_read(void)
{
    return gpio_input_bit_get(KEY0_PORT, KEY0_PIN);
}

/**
 * @description: KEY_WK_UP读取电平函数
 * @return {*}
 */
static uint8_t key_wk_up_read(void)
{
    return gpio_input_bit_get(KEY_WK_UP_PORT, KEY_WK_UP_PIN);
}

/**
 * @description: 升级按钮的触摸返回
 * @return {*}
 */
static uint8_t key_update_read(void)
{
    return touch_in_image(lcddev.width - 80, lcddev.height - 80, lcddev.width - 16, lcddev.height - 16);
}

// 判断图片区域是否被点击
// 参数：sx, sy 起点坐标；ex, ey 终点坐标；tx, ty 当前触摸坐标
// 返回：1 表示点击在区域内；0 表示不在
static uint8_t touch_in_image(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey)
{
    if (tp_dev.sta & TP_PRES_DOWN) // 触摸屏被按下
    {
        if ((tp_dev.x[0] >= sx) && (tp_dev.x[0] <= ex) &&
            (tp_dev.y[0] >= sy) && (tp_dev.y[0] <= ey))
        {
            return 1; // 点击在区域内
        }
    }
    return 0; // 不在区域内
}

void key_register(void)
{
    /* KEY0配置 id分配为1 触发电平为高 单击 长按 超长按 */
    ButtonConfig key0 = {
        .id = KEY0_ID,
        .read_keyValue = key0_read,
        .trigger_level = HIGHT,
        .button_cb = key_event_handler,
        .event_mask = BUTTON_EVT_CLICK | BUTTON_EVT_LONG_PRESS | BUTTON_EVT_VLONG_PRESS};
    Button_Register(&key0);

    /* KEY_WK_UP配置 id分配为2 触发电平为高 单击 长按 超长按 */
    ButtonConfig key_wk_up = {
        .id = KEY_WK_UP_ID,
        .read_keyValue = key_wk_up_read,
        .trigger_level = HIGHT,
        .button_cb = key_event_handler,
        .event_mask = BUTTON_EVT_CLICK | BUTTON_EVT_LONG_PRESS | BUTTON_EVT_VLONG_PRESS};
    Button_Register(&key_wk_up);

    /* KEY_UPDATE配置 id分配为3 触发电平为高 超长按 */
    ButtonConfig key_update = {
        .id = KEY_UPDATE_ID,
        .read_keyValue = key_update_read,
        .trigger_level = HIGHT,
        .button_cb = key_event_handler,
        .event_mask = BUTTON_EVT_LONG_PRESS | BUTTON_EVT_VLONG_PRESS};
    Button_Register(&key_update);
}

/**
 * @description: 按键回调
 * @param {uint8_t} id
 * @param {ButtonEvent} e
 * @return {*}
 */
static void key_event_handler(uint8_t id, ButtonEvent e)
{
    // const char *names[] = {"PRESS_DOWN", "RELEASE", "CLICK", "DOUBLE_CLICK", "LONG_PRESS", "VLONG_PRESS", "CONTINUOS_PRESS"};
    // printf("Button %d: %s\r\n", id, names[e]);
    switch (id)
    {
    case KEY0_ID:
        switch (e)
        {
            /* 按下瞬间 */
        case BUTTON_EVENT_PRESS_DOWN:
            /* code */
            break;

        /* 按键释放 */
        case BUTTON_EVENT_RELEASE:
            /* code */
            break;

        /* 按键单击 */
        case BUTTON_EVENT_CLICK:
            break;

        /* 按键双击 */
        case BUTTON_EVENT_DOUBLE_CLICK:
            /* code */
            break;

        /* 按键长按 */
        case BUTTON_EVENT_LONG_PRESS:
            /* code */
            break;

        /* 按键超长按 */
        case BUTTON_EVENT_VLONG_PRESS:
            /* 擦除APP */
            gd32_erase_app();
            break;

        /* 按键连按事件 */
        case BUTTON_EVENT_CONTINUOS_PRESS:
            /* code */
            break;

        default:
            break;
        }
        break;

    case KEY_WK_UP_ID:
        switch (e)
        {
            /* 按下瞬间 */
        case BUTTON_EVENT_PRESS_DOWN:
            /* code */
            break;

        /* 按键释放 */
        case BUTTON_EVENT_RELEASE:
            /* code */
            break;

        /* 按键单击 */
        case BUTTON_EVENT_CLICK:
            break;

        /* 按键双击 */
        case BUTTON_EVENT_DOUBLE_CLICK:
            /* code */
            break;

        /* 按键长按 */
        case BUTTON_EVENT_LONG_PRESS:
            /* code */
            break;

        /* 按键超长按 */
        case BUTTON_EVENT_VLONG_PRESS:
            /* code */
            break;

        /* 按键连按事件 */
        case BUTTON_EVENT_CONTINUOS_PRESS:
            /* code */
            break;

        default:
            break;
        }
        break;

    case KEY_UPDATE_ID:
        switch (e)
        {
            /* 按下时显示绿色 */
        case BUTTON_EVENT_PRESS_DOWN:
            LCD_ShowPicture(lcddev.width - 80, lcddev.height - 80, 64, 64, gImage_Udate, 0);
            break;
            /* 超长按事件 */
        case BUTTON_EVENT_VLONG_PRESS:
            if (((*(__IO uint32_t *)APP_ADDR) & 0x2FF00000) != 0x20000000)
            {
                /* 应用程序无效，进入BootLoader */
                Set_JumpState(ENABLE);
                lcd_show_string(lcddev.width / 2, 290, (sizeof("Not Application  ") * 8), 16, 16, "Not Application  ", RED);
            }
            else
            {
                /* 手动跳转APP */
                jump_to_app();
            }
            break;
        
            /* 松开后显示回红色 */
        case BUTTON_EVENT_RELEASE:
            LCD_ShowPicture(lcddev.width - 80, lcddev.height - 80, 64, 64, gImage_Udate, 1);
            break;

        default:
            break;
        }
        break;

    default:
        break;
    }
}
